package com.youlai.system.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.youlai.system.common.result.PageResult;
import com.youlai.system.common.result.Result;
import com.youlai.system.model.entity.*;
import com.youlai.system.model.form.ScoreForm;
import com.youlai.system.model.query.ScorePageQuery;
import com.youlai.system.model.query.UserScoreCountPageQuery;
import com.youlai.system.model.vo.ScorePageVO;
import com.youlai.system.model.vo.UserCategoryScoreCountVO;
import com.youlai.system.model.vo.UserCourseScoreCountVO;
import com.youlai.system.model.vo.UserScoreCountPageVO;
import com.youlai.system.plugin.dupsubmit.annotation.PreventDuplicateSubmit;
import com.youlai.system.security.util.SecurityUtils;
import com.youlai.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 成绩控制器
 */
@Tag(name = "15.成绩接口")
@RestController
@RequestMapping("/api/v1/scores")
@RequiredArgsConstructor
public class SysScoreController {

    private final SysScoreService scoreService;

    private final SysUserService userService;

    private final DegreeDataExecService degreeDataExecService;

    private final SysFrequencyService frequencyService;

    private final SysMoldService moldService;

    private final SysQuestionService questionService;


    @Operation(summary = "成绩分页列表")
    @GetMapping("/page")
    public PageResult<ScorePageVO> getScorePage(
            @ParameterObject ScorePageQuery queryParams
    ) {
        if (SecurityUtils.isStudent()) {
            queryParams.setLoginUserId(SecurityUtils.getUserId());
        }
        IPage<ScorePageVO> result = scoreService.getScorePage(queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "用户成绩统计分页列表")
    @GetMapping("/userScoreCountPage")
    public PageResult<UserScoreCountPageVO> getUserScoreCountScorePage(
            @ParameterObject UserScoreCountPageQuery queryParams
    ) {
        if (SecurityUtils.isStudent()) {
            queryParams.setLoginUserId(SecurityUtils.getUserId());
        }
        IPage<UserScoreCountPageVO> result = scoreService.getUserScoreCountPage(queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "单个用户故障成绩汇总数据")
    @GetMapping("/{userId}/userCourseScoreCountSummary")
    public Result<List<UserCourseScoreCountVO>> getUserCourseScoreCount(
            @Parameter(description = "用户ID") @PathVariable Long userId
    ) {
        List<UserCourseScoreCountVO> list = scoreService.getUserCourseScoreCountList(userId);
        return Result.success(list);
    }

    @Operation(summary = "单个用户故障分类成绩汇总数据")
    @GetMapping("/{userId}/userCategoryScoreCountSummary")
    public Result<List<UserCategoryScoreCountVO>> getUserCategoryScoreCount(
            @Parameter(description = "用户ID") @PathVariable Long userId
    ) {
        List<UserCategoryScoreCountVO> list = scoreService.getUserCategoryScoreCountList(userId);
        return Result.success(list);
    }

    @Operation(summary = "新增成绩")
    @PostMapping
    @PreAuthorize("@ss.hasPerm('sys:score:add')")
    @PreventDuplicateSubmit
    public Result saveScore(
            @RequestBody @Valid ScoreForm scoreForm
    ) {
        SysUser user = userService.getByAccount(scoreForm.getStudentCode());
        Long gradeId = user.getGradeId();
        Assert.isTrue(gradeId != null, "司机职级不存在！");
        scoreForm.setGradeId(gradeId);
        SysFrequency frequency = frequencyService.getOneByGradeIdAndCourseId(gradeId, scoreForm.getCourseId());
        Assert.isTrue(frequency != null && frequency.getMoldId() != null, "职级故障科目评估频次不存在！");

        SysMold mold = moldService.getById(frequency.getMoldId());
        Assert.isTrue( mold != null && mold.getFrequency() != null, "职级故障科目故障类型故障评估频次不存在！");
        scoreForm.setFrequency(mold.getFrequency());

        SysQuestion question = questionService.getById(scoreForm.getQuestionId());
        Assert.isTrue(question != null && question.getQuota() != null, "问题分类指标性质不存在！");
        scoreForm.setQuota(question.getQuota());

        boolean result = scoreService.saveScore(user.getId(), scoreForm);
        degreeDataExecService.execSingleStuCourseExam(user.getId(), scoreForm.getCourseId());
        return Result.judge(result);
    }

    @Operation(summary = "成绩表单数据")
    @GetMapping("/{scoreId}/form")
    public Result<ScoreForm> getScoreForm(
            @Parameter(description = "成绩ID") @PathVariable Long scoreId
    ) {
        ScoreForm formData = scoreService.getScoreForm(scoreId);
        return Result.success(formData);
    }


    @Operation(summary = "修改成绩")
    @PutMapping(value = "/{scoreId}")
    @PreAuthorize("@ss.hasPerm('sys:score:edit')")
    public Result updateScore(
            @Parameter(description = "成绩ID") @PathVariable Long scoreId,
            @RequestBody @Validated ScoreForm scoreForm) {
        SysUser user = userService.getByAccount(scoreForm.getStudentCode());
        Long gradeId = user.getGradeId();
        Assert.isTrue(gradeId != null, "司机职级不存在！");
        scoreForm.setGradeId(gradeId);
        SysFrequency frequency = frequencyService.getOneByGradeIdAndCourseId(gradeId, scoreForm.getCourseId());
        Assert.isTrue(frequency != null && frequency.getMoldId() != null, "职级故障科目评估频次不存在！");

        SysMold mold = moldService.getById(frequency.getMoldId());
        Assert.isTrue( mold != null && mold.getFrequency() != null, "职级故障科目故障类型故障评估频次不存在！");
        scoreForm.setFrequency(mold.getFrequency());

        SysQuestion question = questionService.getById(scoreForm.getQuestionId());
        Assert.isTrue(question != null && question.getQuota() != null, "问题分类指标性质不存在！");
        scoreForm.setQuota(question.getQuota());
        boolean result = scoreService.updateScore(scoreId, user.getId(), scoreForm);
        degreeDataExecService.execResetExamPeriodDegreeScore(user.getId(), scoreForm.getCourseId());
        degreeDataExecService.execSingleStuCourseExam(user.getId(), scoreForm.getCourseId());
        return Result.judge(result);
    }

    @Operation(summary = "删除成绩")
    @DeleteMapping("/{ids}")
    @PreAuthorize("@ss.hasPerm('sys:score:delete')")
    public Result deleteScores(
            @Parameter(description = "成绩ID，多个以英文逗号(,)分割") @PathVariable String ids
    ) {
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
        List<SysScore> scoreList = scoreService.listByIds(idList);
        if (CollectionUtil.isNotEmpty(scoreList)) {
            for (SysScore sysScore : scoreList) {
                degreeDataExecService.execResetExamPeriodDegreeScore(sysScore.getStudentId(), sysScore.getCourseId());
            }
        }

        boolean result = scoreService.deleteScores(ids);
        if (CollectionUtil.isNotEmpty(scoreList)) {
            for (SysScore sysScore: scoreList) {
                degreeDataExecService.execSingleStuCourseExam(sysScore.getStudentId(), sysScore.getCourseId());
            }
        }
        return Result.judge(result);
    }

}
